package cc.rengu.igas.share.core.service.channel.cups;

import cc.rengu.igas.channel.cups.facade.base.Header;
import cc.rengu.igas.channel.cups.facade.bean.CupsTermInfo;
import cc.rengu.igas.channel.cups.facade.bean.OrigTxnInfo;
import cc.rengu.igas.channel.cups.facade.request.ConsumeCancelRevsalRequest;
import cc.rengu.igas.channel.cups.facade.response.ConsumeCancelRevsalResponse;
import cc.rengu.igas.channel.cups.facade.result.Result;
import cc.rengu.igas.share.common.constant.ShareParamConstant;
import cc.rengu.igas.share.common.constant.ShareServiceConstant;
import cc.rengu.igas.share.common.constant.TransCacheConstant;
import cc.rengu.igas.share.core.model.MchntInfo;
import cc.rengu.igas.share.core.realize.MchntService;
import cc.rengu.igas.share.core.realize.impl.MchntServiceImpl;
import cc.rengu.oltp.service.base.ChannelBaseService;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.entity.ChannelCallCfg;
import cc.rengu.oltp.service.common.entity.PayOrderInfo;
import cc.rengu.oltp.service.common.enums.ChannelCallModeEnum;
import cc.rengu.oltp.service.common.enums.OltpRpcdEnum;
import cc.rengu.oltp.service.common.enums.TransStatusEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.model.OrderInfo;
import cc.rengu.oltp.service.model.TxnInfo;
import cc.rengu.oltp.service.realize.DubboService;
import cc.rengu.oltp.service.realize.impl.DubboServiceImpl;
import cc.rengu.oltp.utility.util.ConvertUtil;
import cc.rengu.oltp.utility.util.GlobalTransUtil;
import cc.rengu.oltp.utility.util.StringUtil;
import cc.rengu.oltp.utility.util.XmlTreeUtil;
import com.alibaba.fastjson.JSON;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * CUPS消费撤销冲正
 * Created by lzl on 2021/4/23 11:08
 */
public class CupsConsumeCancelRevsalService extends ChannelBaseService {
    @Override
    public Object callPreProc(TxnInfo txnInfo, ChannelCallCfg channelCallCfg, OrderInfo orderInfo) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        Header cupsHeader = new Header();
        cupsHeader.setInstId(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID));
        cupsHeader.setChanlId(channelCallCfg.getMsgSrcId());
        cupsHeader.setSrcSysId(AppParamConstant.SYS_ID);
        cupsHeader.setBizType(AppParamConstant.DEFAULT_BIZ_TYPE);
        cupsHeader.setVersion(ShareParamConstant.DUBBO_VSERSION);
        cupsHeader.setTxnNum(channelCallCfg.getCallChannelTxn());
        cupsHeader.setTraceNo(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM) + channelCallCfg.getCallIndex());
        cupsHeader.setTransTime(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TRANS_TIME));
        cupsHeader.setTransDate(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TRANS_DATE));
        ConsumeCancelRevsalRequest consumeCancelRevsalRequest = new ConsumeCancelRevsalRequest();
        ConvertUtil.convertOutput(consumeCancelRevsalRequest);
        PayOrderInfo origPayOrderInfo = (PayOrderInfo) GlobalTransUtil.getCacheValue(TransCacheConstant.ORIG_PAY_ORDER_INFO);
        consumeCancelRevsalRequest.setHeader(cupsHeader);

        MchntService mchntService = new MchntServiceImpl();
        MchntInfo mchntInfo = mchntService.getMchntInfo(cupsHeader.getInstId(), xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.MCHNT_NO));
        /*设置属性值*/
        String sysNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);

        consumeCancelRevsalRequest.setCupsTraceNo(sysNum.substring(sysNum.length() - 6));
        consumeCancelRevsalRequest.setTransDateTime(cupsHeader.getTransDate().substring(4, 8) + cupsHeader.getTransTime());
        consumeCancelRevsalRequest.setCupsMchntNo(xmlTreeUtil.getXmlTreeStringValue("mchntNo"));
        consumeCancelRevsalRequest.setTermNo(xmlTreeUtil.getXmlTreeStringValue("termNo"));
        consumeCancelRevsalRequest.setMchntShortName(mchntInfo.getMchntSimpleName());
        consumeCancelRevsalRequest.setMchntType(mchntInfo.getIndustryType());
        consumeCancelRevsalRequest.setCupsInstCode(mchntInfo.getCupsInstId());
        consumeCancelRevsalRequest.setFwdInstCode(consumeCancelRevsalRequest.getCupsInstCode());
        consumeCancelRevsalRequest.setOrderAmt(Objects.requireNonNull(origPayOrderInfo).getRealPayAmt());
        consumeCancelRevsalRequest.setOrderCcy(AppParamConstant.DEFAULT_ORDER_CCY);
        consumeCancelRevsalRequest.setPayAcctNo(xmlTreeUtil.getXmlTreeStringValue("cardNo"));
        consumeCancelRevsalRequest.setTrack2Data(xmlTreeUtil.getXmlTreeStringValue("secTractinf"));
        consumeCancelRevsalRequest.setTrack3Data(xmlTreeUtil.getXmlTreeStringValue("thdTractinf"));
        consumeCancelRevsalRequest.setReferenceNo(xmlTreeUtil.getXmlTreeStringValue("referenceNo"));
        consumeCancelRevsalRequest.setEntryMode(xmlTreeUtil.getXmlTreeStringValue("posEntryModeCode"));
        consumeCancelRevsalRequest.setCardSeqNo(xmlTreeUtil.getXmlTreeStringValue("cardSeqid"));
        consumeCancelRevsalRequest.setIcData(xmlTreeUtil.getXmlTreeStringValue("iccData"));
        consumeCancelRevsalRequest.setIcConCode(xmlTreeUtil.getXmlTreeStringValue("posCondCode"));
        /*设置保留域*/
        Map map = new HashMap();
        map.put("branchId", mchntInfo.getInstId());
        map.put("globalTraceNum", " ");
        map.put("globalPathNum", " ");
        String acqReserved = JSON.toJSONString(map);
        consumeCancelRevsalRequest.setAcqReserved(acqReserved);
        /*设置终端信息*/
        CupsTermInfo cupsTermInfo = new CupsTermInfo();
        //BeanUtil.beanCopy(posCardConsumeCancelRevsalRequest.getTermInfo(), cupsTermInfo);
        cupsTermInfo.setLatitude(xmlTreeUtil.getXmlTreeStringValue("termInfo/latitude"));
        cupsTermInfo.setLongitude(xmlTreeUtil.getXmlTreeStringValue("termInfo/longitude"));
        cupsTermInfo.setNetworkLicense(xmlTreeUtil.getXmlTreeStringValue("termInfo/networkLicense"));
        cupsTermInfo.setDeviceType(xmlTreeUtil.getXmlTreeStringValue("termInfo/deviceType"));
        cupsTermInfo.setSerialNum(xmlTreeUtil.getXmlTreeStringValue("termInfo/serialNum"));
        cupsTermInfo.setEncryptRandNum(xmlTreeUtil.getXmlTreeStringValue("termInfo/encryptRandNum"));
        cupsTermInfo.setSecretText(xmlTreeUtil.getXmlTreeStringValue("termInfo/secretText"));
        cupsTermInfo.setAppVersion(xmlTreeUtil.getXmlTreeStringValue("termInfo/appVersion"));
        consumeCancelRevsalRequest.setTermInfo(cupsTermInfo);
        /*设置原交易信息*/
        OrigTxnInfo origTxnInfo = new OrigTxnInfo();
        origTxnInfo.setOriTraceNo(origPayOrderInfo.getChannelOrderId());
        origTxnInfo.setOriTxnDate(origPayOrderInfo.getTxnDate());
        consumeCancelRevsalRequest.setOrigTxnInfo(origTxnInfo);

        rglog.debug("CUPS消费撤销冲正请求:<{}>", JSON.toJSONString(consumeCancelRevsalRequest));
        return consumeCancelRevsalRequest;
    }

    @Override
    public PayOrderInfo generatePayOrderInfo(ChannelCallCfg channelCallCfg, OrderInfo orderInfo, Object request) throws Exception {
        //冲正交易不登记支付订单
        return null;
    }

    @Override
    public Object callProc(ChannelCallCfg channelCallCfg, Object request) throws Exception {
        ConsumeCancelRevsalRequest consumeCancelRevsalRequest = (ConsumeCancelRevsalRequest) request;
        /* Step1：调用接口，获取结果 */
        Result<ConsumeCancelRevsalResponse> callResult;
        DubboService dubboService = new DubboServiceImpl();
        if (AppParamConstant.YES.equals(channelCallCfg.getSyncCallFlag())) {
            /* Step1.1：异步调用 */
            int iReturnCode;
            int callTimes = 0 == channelCallCfg.getSyncQueryRepeatNum() ? 1 : channelCallCfg.getSyncQueryRepeatNum();
            int gatTime = channelCallCfg.getSyncQueryRepeatTime();
            int gatType = StringUtil.isEmptyOrNull(channelCallCfg.getSyncQueryGapType()) ? 0 : Integer.parseInt(channelCallCfg.getSyncQueryGapType());
            if (ChannelCallModeEnum.LOCAL.getMode().equals(channelCallCfg.getChannelCallMode())) {
                /* Step1.1.1：异步应用内调用 */
                Class clasz = Class.forName(ShareServiceConstant.CUPS_SERVICE_INNER_PATH);
                iReturnCode = dubboService.asynCallDubboInnerMethod(clasz, ShareServiceConstant.CUPS_CONSUME_CANCEL_REVSAL_METHOD, consumeCancelRevsalRequest, channelCallCfg.getSyncResultServiceName(), callTimes, gatType, gatTime);
            } else if (ChannelCallModeEnum.REMOTE.getMode().equals(channelCallCfg.getChannelCallMode())) {
                /* Step1.1.2：异步远程调用 */
                iReturnCode = dubboService.asynCallDubboService(ShareServiceConstant.CUPS_SERVICE, ShareServiceConstant.CUPS_CONSUME_CANCEL_REVSAL_METHOD, consumeCancelRevsalRequest, channelCallCfg.getSyncResultServiceName(), callTimes, gatType, gatTime);
            } else {
                rglog.error("不支持的通道服务调用方式:{}，交易拒绝!", channelCallCfg.getChannelCallMode());
                throw new BizException(OltpRpcdEnum.CALL_BIZ_SERVICE_ERROR);
            }
            if (0 == iReturnCode) {
                return new BizResponse<>(OltpRpcdEnum.TRANS_SUCCESS.getRespCode(), OltpRpcdEnum.TRANS_SUCCESS.getRespDesc());
            } else {
                return new BizResponse<>(OltpRpcdEnum.CALL_BIZ_SERVICE_ERROR.getRespCode(), OltpRpcdEnum.CALL_BIZ_SERVICE_ERROR.getRespDesc());
            }
        } else {
            /* Step1.2：同步调用 */
            if (ChannelCallModeEnum.LOCAL.getMode().equals(channelCallCfg.getChannelCallMode())) {
                /* Step1.2.1：同步应用内调用 */
                Class clasz = Class.forName(ShareServiceConstant.CUPS_SERVICE_INNER_PATH);
                callResult = (Result<ConsumeCancelRevsalResponse>) dubboService.callDubboInnerMethod(clasz, ShareServiceConstant.CUPS_CONSUME_CANCEL_REVSAL_METHOD, consumeCancelRevsalRequest);
            } else if (ChannelCallModeEnum.REMOTE.getMode().equals(channelCallCfg.getChannelCallMode())) {
                /* Step1.2.2：同步远程调用 */
                callResult = (Result<ConsumeCancelRevsalResponse>) dubboService.callDubboService(ShareServiceConstant.CUPS_SERVICE, ShareServiceConstant.CUPS_CONSUME_CANCEL_REVSAL_METHOD, consumeCancelRevsalRequest);
            } else {
                rglog.error("不支持的通道服务调用方式:{}，交易拒绝!", channelCallCfg.getChannelCallMode());
                throw new BizException(OltpRpcdEnum.CALL_BIZ_SERVICE_ERROR);
            }
        }
        return callResult;
    }

    @Override
    public Object querySyncCallResult(PayOrderInfo payOrderInfo, Object request) {
        return null;
    }

    @Override
    public OrderInfo callResultOrderProc(OrderInfo orderInfo, String payOrderIndex, TransStatusEnum transStatusEnum, Object response) {
        return null;
    }

}
